﻿using System;


namespace BizElements.BusinessLayer
{
    /// <summary>
    /// Represents a single or a set of values with optional name and description.
    /// </summary>
    public interface INamedValueSet : ICloneable
    {
        #region Properties.

        /// <summary>
        /// Gets the type of data structure contained in the current instance.
        /// </summary>
        NamedValueSetType ValueSetType { get; }

        /// <summary>
        /// Gets the values contained in the current instance.
        /// </summary>
        Array Values { get; }

        /// <summary>
        /// Gets the key of the set.
        /// </summary>
        /// <remarks>Key value should be unique in the collection. Implementations should return 
        /// <see cref="Name"/> value if Key property wasn't explicitly set.</remarks>
        string Key { get; }

        /// <summary>
        /// Gets the name of the set.
        /// </summary>
        string Name { get; }

        /// <summary>
        /// Gets the description of the set.
        /// </summary>
        string Description { get; }

        #endregion

        #region Methods.

        /// <summary>
        /// Gets the value contained in the <see cref="NamedValueSetType.SingleValue"/> set type.
        /// </summary>
        /// <returns>A single value.</returns>
        /// <remarks>Interface implementor should throw a <see cref="InvalidOperationException"/> if the current 
        /// instance does not represent a <see cref="NamedValueSetType.SingleValue"/> set type.</remarks>
        object GetSingleValue();

        /// <summary>
        /// Gets the begin and end values of the interval represented by the <see cref="NamedValueSetType.Interval"/> set type.
        /// </summary>
        /// <param name="beginValue">Interval begin value.</param>
        /// <param name="endValue">Interval end value.</param>
        /// <remarks>Interface implementor should throw a <see cref="InvalidOperationException"/> if the current 
        /// instance does not represent a <see cref="NamedValueSetType.Interval"/> set type.</remarks>
        void GetInterval(out object beginValue, out object endValue);

        /// <summary>
        /// Gets the list of values contained in the <see cref="NamedValueSetType.ListOfValues"/> set type.
        /// </summary>
        /// <returns>Array of values.</returns>
        /// <remarks>Interface implementor should throw a <see cref="InvalidOperationException"/> if the current 
        /// instance does not represent a <see cref="NamedValueSetType.ListOfValues"/> set type.</remarks>
        Array GetListOfValues();

        #endregion
    }

    /// <summary>
    /// Represents a strong-typed (generic) named value set.
    /// </summary>
    /// <typeparam name="T">The type of values.</typeparam>
    public interface INamedValueSet<T> : INamedValueSet
    {
        #region Properties.

        /// <summary>
        /// Gets the values contained in the current instance.
        /// </summary>
        new T[] Values { get; }

        #endregion

        #region Methods.

        /// <summary>
        /// Gets the value contained in the <see cref="NamedValueSetType.SingleValue"/> set type.
        /// </summary>
        /// <returns>A single value.</returns>
        /// <remarks>Interface implementor should throw a <see cref="InvalidOperationException"/> if the current 
        /// instance does not represent a <see cref="NamedValueSetType.SingleValue"/> set type.</remarks>
        new T GetSingleValue();

        /// <summary>
        /// Gets the begin and end values of the interval represented by the <see cref="NamedValueSetType.Interval"/> set type.
        /// </summary>
        /// <param name="beginValue">Interval begin value.</param>
        /// <param name="endValue">Interval end value.</param>
        /// <remarks>Interface implementor should throw a <see cref="InvalidOperationException"/> if the current 
        /// instance does not represent a <see cref="NamedValueSetType.Interval"/> set type.</remarks>
        void GetInterval(out T beginValue, out T endValue);

        /// <summary>
        /// Gets the list of values contained in the <see cref="NamedValueSetType.ListOfValues"/> set type.
        /// </summary>
        /// <returns>Array of values.</returns>
        /// <remarks>Interface implementor should throw a <see cref="InvalidOperationException"/> if the current 
        /// instance does not represent a <see cref="NamedValueSetType.ListOfValues"/> set type.</remarks>
        new T[] GetListOfValues();

        #endregion
    }
}